<!DOCTYPE html>
<html>
<head hexo-theme='https://volantis.js.org/#2.6.6'>
  <meta charset="utf-8">
  <!-- SEO相关 -->
  
    
  
  <!-- 渲染优化 -->
  <meta name="renderer" content="webkit">
  <meta name="force-rendering" content="webkit">
  <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
  <meta name="HandheldFriendly" content="True" >
  <meta name="apple-mobile-web-app-capable" content="yes">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

  <!-- 页面元数据 -->
  
    <title>B002 Classification - SGD Method - Jun&#39;s Blog</title>
  
    <meta name="keywords" content="AI,Python,Machine Learning">
  
  
    <meta name="description" content="What is a classification problem?
Imagine an elementary school student is given a batch of learning materials: lots of pictures of handwitten digits. His pa...">
  

  <!-- feed -->
  
    <link rel="alternate" href="/junblog/atom.xml" title="Jun's Blog">
  

  <!-- import meta -->
  

  <!-- link -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5.13/css/all.min.css">
  
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.css">

  
  
    
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/node-waves@0.7.6/dist/waves.min.css">

  

  
  <link rel="shortcut icon" type='image/x-icon' href="https://cdn.jsdelivr.net/gh/xaoxuu/assets@master/favicon/favicon.ico">
  

  

  

  <!-- import link -->
  

  
  
    
<link rel="stylesheet" href="/junblog/css/style.css">

  

  <script>
    function setLoadingBarProgress(num) {
      document.getElementById('loading-bar').style.width=num+"%";
    }
  </script>

  
  
</head>

<body>
  
  <div id="loading-bar-wrapper">
  <div id="loading-bar"></div>
</div>
<header class="l_header shadow blur">
  <div class='container'>
  <div class='wrapper'>
    <div class='nav-sub'>
      <p class="title"></p>
      <ul class='switcher nav-list-h'>
        <li><a class="s-comment fas fa-comments fa-fw" target="_self" href='javascript:void(0)'></a></li>
        
          <li><a class="s-toc fas fa-list fa-fw" target="_self" href='javascript:void(0)'></a></li>
        
      </ul>
    </div>
		<div class="nav-main">
      
        
        <a class="title flat-box" target="_self" href='/junblog/'>
          
          
          
            Jun's Blog
          
          
        </a>
      

			<div class='menu navigation'>
				<ul class='nav-list-h'>
          
          
          
            
            
              <li>
                <a class="flat-box" href=/junblog/
                  
                  
                  
                    id="junblog"
                  >
                  <i class='fas fa-rss fa-fw'></i>首页
                </a>
                
              </li>
            
          
          
            
            
              <li>
                <a class="flat-box" href=/junblog/categories/
                  
                  
                  
                    id="junblogcategories"
                  >
                  <i class='fas fa-folder-open fa-fw'></i>分类
                </a>
                
              </li>
            
          
          
            
            
              <li>
                <a class="flat-box" href=/junblog/tags/
                  
                  
                  
                    id="junblogtags"
                  >
                  <i class='fas fa-tags fa-fw'></i>标签
                </a>
                
              </li>
            
          
          
            
            
              <li>
                <a class="flat-box" href=/junblog/archives/
                  
                  
                  
                    id="junblogarchives"
                  >
                  <i class='fas fa-archive fa-fw'></i>归档
                </a>
                
              </li>
            
          
          
            
            
              <li>
                <a class="flat-box" href=/junblog/friends/
                  
                  
                  
                    id="junblogfriends"
                  >
                  <i class='fas fa-link fa-fw'></i>友链
                </a>
                
              </li>
            
          
          
            
            
              <li>
                <a class="flat-box" href=/junblog/aboutme/
                  
                  
                  
                    id="junblogaboutme"
                  >
                  <i class='fas fa-info-circle fa-fw'></i>关于
                </a>
                
              </li>
            
          
          
				</ul>
			</div>

      <div class="m_search">
        <form name="searchform" class="form u-search-form">
          <i class="icon fas fa-search fa-fw"></i>
          <input type="text" class="input u-search-input" placeholder="Search..." />
        </form>
      </div>

			<ul class='switcher nav-list-h'>
				
					<li><a class="s-search fas fa-search fa-fw" target="_self" href='javascript:void(0)'></a></li>
				
				<li>
          <a class="s-menu fas fa-bars fa-fw" target="_self" href='javascript:void(0)'></a>
          <ul class="menu-phone list-v navigation white-box">
            
              
            
              <li>
                <a class="flat-box" href=/junblog/
                  
                  
                  
                    id="junblog"
                  >
                  <i class='fas fa-rss fa-fw'></i>首页
                </a>
                
              </li>
            
          
            
              
            
              <li>
                <a class="flat-box" href=/junblog/categories/
                  
                  
                  
                    id="junblogcategories"
                  >
                  <i class='fas fa-folder-open fa-fw'></i>分类
                </a>
                
              </li>
            
          
            
              
            
              <li>
                <a class="flat-box" href=/junblog/tags/
                  
                  
                  
                    id="junblogtags"
                  >
                  <i class='fas fa-tags fa-fw'></i>标签
                </a>
                
              </li>
            
          
            
              
            
              <li>
                <a class="flat-box" href=/junblog/archives/
                  
                  
                  
                    id="junblogarchives"
                  >
                  <i class='fas fa-archive fa-fw'></i>归档
                </a>
                
              </li>
            
          
            
              
            
              <li>
                <a class="flat-box" href=/junblog/friends/
                  
                  
                  
                    id="junblogfriends"
                  >
                  <i class='fas fa-link fa-fw'></i>友链
                </a>
                
              </li>
            
          
            
              
            
              <li>
                <a class="flat-box" href=/junblog/aboutme/
                  
                  
                  
                    id="junblogaboutme"
                  >
                  <i class='fas fa-info-circle fa-fw'></i>关于
                </a>
                
              </li>
            
          
            
          </ul>
        </li>
			</ul>
		</div>
	</div>
  </div>
</header>

<script>setLoadingBarProgress(40);</script>



  <div class="l_body nocover">
    <div class='body-wrapper'>
      

<div class='l_main'>
  

  
    <article id="post" class="post white-box reveal blur article-type-post" itemscope itemprop="blogPost">
      


  <section class='meta'>
    
      
      
      <div class="meta" id="header-meta">
        
          
  <h1 class="title">
    <a href="/junblog/2021/02/11/B002%20Classification%20-%20SGD/">
      B002 Classification - SGD Method
    </a>
  </h1>


        
        <div class='new-meta-box'>
          
            
          
            
              
<div class='new-meta-item author'>
  <a href="" rel="nofollow">
    <img src="https://cdn.jsdelivr.net/gh/JunyuanHe/cdn-assets@master/img/GeographicObjects2.jpg">
    <p>Jun</p>
  </a>
</div>

            
          
            
              
  
  <div class='new-meta-item category'>
    <a href='/junblog/categories/AI/' rel="nofollow">
      <i class="fas fa-folder-open fa-fw" aria-hidden="true"></i>
      <p>AI</p>
    </a>
  </div>


            
          
            
              <div class="new-meta-item date">
  <a class='notlink'>
    <i class="fas fa-calendar-alt fa-fw" aria-hidden="true"></i>
    <p>发布于：2021年2月11日 23:04</p>
  </a>
</div>

            
          
            
              

            
          
        </div>
        
          <hr>
        
      </div>
    
  </section>


      <section class="article typo">
        <div class="article-entry" itemprop="articleBody">
          
          
          <h2 id="what-is-a-classification-problem">What is a classification problem?</h2>
<p>Imagine an elementary school student is given a batch of learning materials: lots of pictures of handwitten digits. His parents is teaching him, "this is 1, o-n-e, one.""That is 5, f-i-v-e, five". And the student gradually learn to identify the digits 0~9 by their shapes. Now, whoever write a number, the little boy can name it correctly.</p>
<p>The above process is what classification problems look like:</p>
<ul>
<li>First, given a dataset with labels, called training set, to the machine</li>
<li>Next, using some kind of algorithm, the machine learns to classify data of different labels based on the training set.</li>
<li>Then, we can use a test set to check the effectiveness of the learning process. If the machine is not satisfying, we can improve the algorithm or give better training sets to retrain the computer, until it is satisfying.</li>
<li>Finally, the machine can be put into practical use.</li>
</ul>
<a id="more"></a>
<h2 id="sgd-as-a-binary-classifier">SGD as a binary classifier</h2>
<p>A binary classification problem is the easiest among all. It is like a "yes-or-no" question, with only two choices. Stochastic Gradient Descent method is a popular and relatively elementary method in solving the problem.</p>
<p>SGD(Stochastic Gradient Descent) Classifier has a good performance when handling large datasets. Scikit-learn has a <code>SGDClassifier</code> class for this algorithm.</p>
<p>First, prepare the dataset.</p>
<p>Here, we use the MINST dataset (handwritten digits of 0~9) as an example.</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> struct</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"></span><br><span class="line"><span class="comment"># train_images</span></span><br><span class="line">train_images_idx3_ubyte_file = <span class="string">"dataset/MINST/train-images.idx3-ubyte"</span></span><br><span class="line"><span class="comment"># train_labels</span></span><br><span class="line">train_labels_idx1_ubyte_file = <span class="string">"dataset/MINST/train-labels.idx1-ubyte"</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># test_images</span></span><br><span class="line">test_images_idx3_ubyte_file = <span class="string">"dataset/MINST/t10k-images.idx3-ubyte"</span></span><br><span class="line"><span class="comment"># test_labels</span></span><br><span class="line">test_labels_idx1_ubyte_file = <span class="string">"dataset/MINST/t10k-labels.idx1-ubyte"</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">decode_idx3_ubyte</span><span class="params">(idx3_ubyte_file)</span>:</span></span><br><span class="line">    <span class="string">"""</span></span><br><span class="line"><span class="string">    A universal function for decoding idx3 files</span></span><br><span class="line"><span class="string">    :param idx3_ubyte_file: idx3 file path</span></span><br><span class="line"><span class="string">    :return: dataset</span></span><br><span class="line"><span class="string">    """</span></span><br><span class="line">    <span class="comment"># 读取二进制数据</span></span><br><span class="line">    bin_data = open(idx3_ubyte_file, <span class="string">"rb"</span>).read()</span><br><span class="line"></span><br><span class="line">    <span class="comment"># 解析文件头信息，依次为魔数、图片数量、每张图片高、每张图片宽</span></span><br><span class="line">    offset = <span class="number">0</span></span><br><span class="line">    fmt_header = <span class="string">"&gt;iiii"</span>  <span class="comment"># 因为数据结构中前4行的数据类型都是32位整型，所以采用i格式，但我们需要读取前4行数据，所以需要4个i。我们后面会看到标签集中，只使用2个ii。</span></span><br><span class="line">    magic_number, num_images, num_rows, num_cols = struct.unpack_from(</span><br><span class="line">        fmt_header, bin_data, offset</span><br><span class="line">    )</span><br><span class="line">    print(</span><br><span class="line">        <span class="string">"魔数:%d, 图片数量: %d张, 图片大小: %d*%d"</span> % (magic_number, num_images, num_rows, num_cols)</span><br><span class="line">    )</span><br><span class="line"></span><br><span class="line">    <span class="comment"># 解析数据集</span></span><br><span class="line">    image_size = num_rows * num_cols</span><br><span class="line">    offset += struct.calcsize(</span><br><span class="line">        fmt_header</span><br><span class="line">    )  <span class="comment"># 获得数据在缓存中的指针位置，从前面介绍的数据结构可以看出，读取了前4行之后，指针位置（即偏移位置offset）指向0016。</span></span><br><span class="line">    print(offset)</span><br><span class="line">    fmt_image = (</span><br><span class="line">        <span class="string">"&gt;"</span> + str(image_size) + <span class="string">"B"</span></span><br><span class="line">    )  <span class="comment"># 图像数据像素值的类型为unsigned char型，对应的format格式为B。这里还有加上图像大小784，是为了读取784个B格式数据，如果没有则只会读取一个值（即一副图像中的一个像素值）</span></span><br><span class="line">    print(fmt_image, offset, struct.calcsize(fmt_image))</span><br><span class="line">    images = np.empty((num_images, num_rows, num_cols))</span><br><span class="line">    <span class="comment"># plt.figure()</span></span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> range(num_images):</span><br><span class="line">        <span class="keyword">if</span> (i + <span class="number">1</span>) % <span class="number">10000</span> == <span class="number">0</span>:</span><br><span class="line">            print(<span class="string">"已解析 %d"</span> % (i + <span class="number">1</span>) + <span class="string">"张"</span>)</span><br><span class="line">            print(offset)</span><br><span class="line">        images[i] = np.array(struct.unpack_from(fmt_image, bin_data, offset)).reshape(</span><br><span class="line">            (num_rows, num_cols)</span><br><span class="line">        )</span><br><span class="line">        <span class="comment"># print(images[i])</span></span><br><span class="line">        offset += struct.calcsize(fmt_image)</span><br><span class="line">    <span class="comment">#        plt.imshow(images[i],'gray')</span></span><br><span class="line">    <span class="comment">#        plt.pause(0.00001)</span></span><br><span class="line">    <span class="comment">#        plt.show()</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> images</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">decode_idx1_ubyte</span><span class="params">(idx1_ubyte_file)</span>:</span></span><br><span class="line">    <span class="string">"""</span></span><br><span class="line"><span class="string">    A universal function for decoding idx1 files</span></span><br><span class="line"><span class="string">    :param idx1_ubyte_file: idx1 file path</span></span><br><span class="line"><span class="string">    :return: dataset</span></span><br><span class="line"><span class="string">    """</span></span><br><span class="line">    <span class="comment"># 读取二进制数据</span></span><br><span class="line">    bin_data = open(idx1_ubyte_file, <span class="string">"rb"</span>).read()</span><br><span class="line"></span><br><span class="line">    <span class="comment"># 解析文件头信息，依次为魔数和标签数</span></span><br><span class="line">    offset = <span class="number">0</span></span><br><span class="line">    fmt_header = <span class="string">"&gt;ii"</span></span><br><span class="line">    magic_number, num_images = struct.unpack_from(fmt_header, bin_data, offset)</span><br><span class="line">    print(<span class="string">"魔数:%d, 图片数量: %d张"</span> % (magic_number, num_images))</span><br><span class="line"></span><br><span class="line">    <span class="comment"># 解析数据集</span></span><br><span class="line">    offset += struct.calcsize(fmt_header)</span><br><span class="line">    fmt_image = <span class="string">"&gt;B"</span></span><br><span class="line">    labels = np.empty(num_images)</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> range(num_images):</span><br><span class="line">        <span class="keyword">if</span> (i + <span class="number">1</span>) % <span class="number">10000</span> == <span class="number">0</span>:</span><br><span class="line">            print(<span class="string">"已解析 %d"</span> % (i + <span class="number">1</span>) + <span class="string">"张"</span>)</span><br><span class="line">        labels[i] = struct.unpack_from(fmt_image, bin_data, offset)[<span class="number">0</span>]</span><br><span class="line">        offset += struct.calcsize(fmt_image)</span><br><span class="line">    <span class="keyword">return</span> labels</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">load_train_images</span><span class="params">(idx_ubyte_file=train_images_idx3_ubyte_file)</span>:</span></span><br><span class="line">    <span class="string">"""</span></span><br><span class="line"><span class="string">    TRAINING SET IMAGE FILE (train-images-idx3-ubyte):</span></span><br><span class="line"><span class="string">    [offset] [type]          [value]          [description]</span></span><br><span class="line"><span class="string">    0000     32 bit integer  0x00000803(2051) magic number</span></span><br><span class="line"><span class="string">    0004     32 bit integer  60000            number of images</span></span><br><span class="line"><span class="string">    0008     32 bit integer  28               number of rows</span></span><br><span class="line"><span class="string">    0012     32 bit integer  28               number of columns</span></span><br><span class="line"><span class="string">    0016     unsigned byte   ??               pixel</span></span><br><span class="line"><span class="string">    0017     unsigned byte   ??               pixel</span></span><br><span class="line"><span class="string">    ........</span></span><br><span class="line"><span class="string">    xxxx     unsigned byte   ??               pixel</span></span><br><span class="line"><span class="string">    Pixels are organized row-wise. Pixel values are 0 to 255. 0 means background (white), 255 means foreground (black).</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">    :param idx_ubyte_file: idx file path</span></span><br><span class="line"><span class="string">    :return: n*row*col维np.array对象，n为图片数量</span></span><br><span class="line"><span class="string">    """</span></span><br><span class="line">    <span class="keyword">return</span> decode_idx3_ubyte(idx_ubyte_file)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">load_train_labels</span><span class="params">(idx_ubyte_file=train_labels_idx1_ubyte_file)</span>:</span></span><br><span class="line">    <span class="string">"""</span></span><br><span class="line"><span class="string">    TRAINING SET LABEL FILE (train-labels-idx1-ubyte):</span></span><br><span class="line"><span class="string">    [offset] [type]          [value]          [description]</span></span><br><span class="line"><span class="string">    0000     32 bit integer  0x00000801(2049) magic number (MSB first)</span></span><br><span class="line"><span class="string">    0004     32 bit integer  60000            number of items</span></span><br><span class="line"><span class="string">    0008     unsigned byte   ??               label</span></span><br><span class="line"><span class="string">    0009     unsigned byte   ??               label</span></span><br><span class="line"><span class="string">    ........</span></span><br><span class="line"><span class="string">    xxxx     unsigned byte   ??               label</span></span><br><span class="line"><span class="string">    The labels values are 0 to 9.</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">    :param idx_ubyte_file: idx文件路径</span></span><br><span class="line"><span class="string">    :return: n*1维np.array对象，n为图片数量</span></span><br><span class="line"><span class="string">    """</span></span><br><span class="line">    <span class="keyword">return</span> decode_idx1_ubyte(idx_ubyte_file)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">load_test_images</span><span class="params">(idx_ubyte_file=test_images_idx3_ubyte_file)</span>:</span></span><br><span class="line">    <span class="string">"""</span></span><br><span class="line"><span class="string">    TEST SET IMAGE FILE (t10k-images-idx3-ubyte):</span></span><br><span class="line"><span class="string">    [offset] [type]          [value]          [description]</span></span><br><span class="line"><span class="string">    0000     32 bit integer  0x00000803(2051) magic number</span></span><br><span class="line"><span class="string">    0004     32 bit integer  10000            number of images</span></span><br><span class="line"><span class="string">    0008     32 bit integer  28               number of rows</span></span><br><span class="line"><span class="string">    0012     32 bit integer  28               number of columns</span></span><br><span class="line"><span class="string">    0016     unsigned byte   ??               pixel</span></span><br><span class="line"><span class="string">    0017     unsigned byte   ??               pixel</span></span><br><span class="line"><span class="string">    ........</span></span><br><span class="line"><span class="string">    xxxx     unsigned byte   ??               pixel</span></span><br><span class="line"><span class="string">    Pixels are organized row-wise. Pixel values are 0 to 255. 0 means background (white), 255 means foreground (black).</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">    :param idx_ubyte_file: idx文件路径</span></span><br><span class="line"><span class="string">    :return: n*row*col维np.array对象，n为图片数量</span></span><br><span class="line"><span class="string">    """</span></span><br><span class="line">    <span class="keyword">return</span> decode_idx3_ubyte(idx_ubyte_file)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">load_test_labels</span><span class="params">(idx_ubyte_file=test_labels_idx1_ubyte_file)</span>:</span></span><br><span class="line">    <span class="string">"""</span></span><br><span class="line"><span class="string">    TEST SET LABEL FILE (t10k-labels-idx1-ubyte):</span></span><br><span class="line"><span class="string">    [offset] [type]          [value]          [description]</span></span><br><span class="line"><span class="string">    0000     32 bit integer  0x00000801(2049) magic number (MSB first)</span></span><br><span class="line"><span class="string">    0004     32 bit integer  10000            number of items</span></span><br><span class="line"><span class="string">    0008     unsigned byte   ??               label</span></span><br><span class="line"><span class="string">    0009     unsigned byte   ??               label</span></span><br><span class="line"><span class="string">    ........</span></span><br><span class="line"><span class="string">    xxxx     unsigned byte   ??               label</span></span><br><span class="line"><span class="string">    The labels values are 0 to 9.</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">    :param idx_ubyte_file: idx文件路径</span></span><br><span class="line"><span class="string">    :return: n*1维np.array对象，n为图片数量</span></span><br><span class="line"><span class="string">    """</span></span><br><span class="line">    <span class="keyword">return</span> decode_idx1_ubyte(idx_ubyte_file)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">"__main__"</span>:</span><br><span class="line">    train_images = load_train_images()</span><br><span class="line">    train_labels = load_train_labels()</span><br><span class="line">    test_images = load_test_images()</span><br><span class="line">    test_labels = load_test_labels()</span><br><span class="line"></span><br><span class="line">    <span class="comment"># 查看前十个数据及其标签以读取是否正确</span></span><br><span class="line"><span class="comment">#     for i in range(10):</span></span><br><span class="line"><span class="comment">#         print(train_labels[i])</span></span><br><span class="line"><span class="comment">#         plt.imshow(train_images[i], cmap='gray')</span></span><br><span class="line"><span class="comment">#         plt.pause(0.000001)</span></span><br><span class="line"><span class="comment">#         plt.show()</span></span><br><span class="line"><span class="comment">#     print('done')</span></span><br></pre></td></tr></table></figure>
<pre><code>魔数:2051, 图片数量: 60000张, 图片大小: 28*28
16
&gt;784B 16 784
已解析 10000张
7839232
已解析 20000张
15679232
已解析 30000张
23519232
已解析 40000张
31359232
已解析 50000张
39199232
已解析 60000张
47039232
魔数:2049, 图片数量: 60000张
已解析 10000张
已解析 20000张
已解析 30000张
已解析 40000张
已解析 50000张
已解析 60000张
魔数:2051, 图片数量: 10000张, 图片大小: 28*28
16
&gt;784B 16 784
已解析 10000张
7839232
魔数:2049, 图片数量: 10000张
已解析 10000张</code></pre>
<blockquote>
<p>The above code used https://blog.csdn.net/panrenlong/article/details/81736754 as a reference.</p>
</blockquote>
<p>We then solve the following classification problem: 3 or not-3.</p>
<p>In order to enhance training effects, we shuffle the index of the training set.</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">shuffle_index = np.random.permutation(<span class="number">60000</span>)</span><br><span class="line">train_images, train_labels = train_images[shuffle_index], train_labels[shuffle_index]</span><br><span class="line"></span><br><span class="line">X_train = np.empty((<span class="number">60000</span>, <span class="number">28</span> * <span class="number">28</span>))</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">0</span>, <span class="number">60000</span>):</span><br><span class="line">    X_train[i] = train_images[i].flatten()</span><br><span class="line"></span><br><span class="line">X_test = np.empty((<span class="number">10000</span>, <span class="number">28</span> * <span class="number">28</span>))</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">0</span>, <span class="number">10000</span>):</span><br><span class="line">    test_images[i].flatten()</span><br><span class="line"></span><br><span class="line">y_train, y_test = train_labels, test_labels</span><br></pre></td></tr></table></figure>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">y_train_3 = y_train == <span class="number">3</span></span><br><span class="line">y_test_3 = y_test == <span class="number">3</span></span><br><span class="line"></span><br><span class="line">print(X_train)</span><br><span class="line">print(y_train_3)</span><br><span class="line">print(y_test_3)</span><br></pre></td></tr></table></figure>
<pre><code>[[0. 0. 0. ... 0. 0. 0.]
 [0. 0. 0. ... 0. 0. 0.]
 [0. 0. 0. ... 0. 0. 0.]
 ...
 [0. 0. 0. ... 0. 0. 0.]
 [0. 0. 0. ... 0. 0. 0.]
 [0. 0. 0. ... 0. 0. 0.]]
[False False False ... False False False]
[False False False ... False False False]</code></pre>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> sklearn.linear_model <span class="keyword">import</span> SGDClassifier</span><br><span class="line"></span><br><span class="line">sgd_clf = SGDClassifier(random_state=<span class="number">42</span>)</span><br><span class="line">sgd_clf.fit(X_train, y_train_3)</span><br></pre></td></tr></table></figure>
<pre><code>SGDClassifier(random_state=42)</code></pre>
<p>We assess the accuracy of the model in a simple way:</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">success = <span class="number">0.0</span></span><br><span class="line">total = <span class="number">0.0</span></span><br><span class="line">rate = <span class="number">0.0</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">0</span>, <span class="number">10000</span>):</span><br><span class="line">    res = sgd_clf.predict([X_test[i]])</span><br><span class="line">    <span class="keyword">if</span> res[<span class="number">0</span>] == y_test_3[i]:</span><br><span class="line">        success += <span class="number">1</span></span><br><span class="line">    total += <span class="number">1</span></span><br><span class="line">rate = success / total</span><br><span class="line">print(<span class="string">"The accuracy on the test set is &#123;0&#125;"</span>.format(rate))</span><br></pre></td></tr></table></figure>
<pre><code>The accuracy on the test set is 0.899</code></pre>
<h2 id="mathematical-explanation-of-sgd-method">Mathematical explanation of SGD method</h2>
<p>A mathematical explanation of Perceptron and SGD method is given below:</p>
<figure>
<img src="/junblog/2021/02/11/B002%20Classification%20-%20SGD/Mathematical%20Explanation%20of%20SGD.jpg" alt="Mathematical Explanation of SGD Method"><figcaption aria-hidden="true">Mathematical Explanation of SGD Method</figcaption>
</figure>
<p>Base on the mathematical explanation, we will then implement the SGD algorithm by ourselves.</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">SGD</span>:</span></span><br><span class="line">    omega = <span class="number">0</span></span><br><span class="line">    b = <span class="number">0</span></span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self, omega, b)</span>:</span></span><br><span class="line">        self.omega = omega</span><br><span class="line">        self.b = b</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">predict</span><span class="params">(self, x_predict)</span>:</span></span><br><span class="line">        x_predict = np.array(x_predict)</span><br><span class="line">        dim = x_predict[<span class="number">0</span>].size</span><br><span class="line">        all_size = x_predict.size</span><br><span class="line">        size = int(all_size/dim)</span><br><span class="line">        y_predict = np.empty(size, bool)</span><br><span class="line">        <span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">0</span>,size):</span><br><span class="line">            y_predict[i] = ((np.dot(self.omega.T, x_predict[i]) + self.b) &gt;= <span class="number">0</span>)</span><br><span class="line">        <span class="keyword">return</span> y_predict</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">SGD_train</span><span class="params">(x_train, y_train_ori, learning_rate = <span class="number">0.5</span>, max_iter = <span class="number">50000</span>)</span>:</span></span><br><span class="line">    <span class="string">"""</span></span><br><span class="line"><span class="string">    :param x_train: 2-D ndarray</span></span><br><span class="line"><span class="string">    :param y_train: 1-D ndarray</span></span><br><span class="line"><span class="string">    :param learning_rate: float number in (0,1]</span></span><br><span class="line"><span class="string">    :return: perceptron object</span></span><br><span class="line"><span class="string">    """</span></span><br><span class="line"></span><br><span class="line">    <span class="comment"># fetch the size of the training data</span></span><br><span class="line">    size = y_train_ori.size</span><br><span class="line">    dim = x_train[<span class="number">0</span>].size</span><br><span class="line"></span><br><span class="line">    y_train = y_train_ori*<span class="number">2</span><span class="number">-1</span></span><br><span class="line">    print(y_train)</span><br><span class="line"></span><br><span class="line">    <span class="comment"># Choose the initial value omega, b</span></span><br><span class="line">    omega = np.zeros(dim)</span><br><span class="line">    b = <span class="number">0.0</span></span><br><span class="line">    learning_rate = <span class="number">1</span></span><br><span class="line"></span><br><span class="line">    correct_iter = <span class="number">0</span></span><br><span class="line">    counter = <span class="number">0</span></span><br><span class="line">    best_omega = np.zeros(dim)</span><br><span class="line">    best_b = <span class="number">0</span></span><br><span class="line">    largest_iter = <span class="number">0</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line">        <span class="comment"># Randomly choose data in the data set</span></span><br><span class="line">        i = np.random.randint(<span class="number">0</span>, size)</span><br><span class="line">        <span class="keyword">if</span> (y_train[i] * (np.dot(omega.T, x_train[i]) + b)) &lt;= <span class="number">0</span>:</span><br><span class="line">            omega = omega + learning_rate * y_train[i] * x_train[i]</span><br><span class="line">            b = b + learning_rate * y_train[i]</span><br><span class="line">            <span class="comment"># print('iteration &#123;0&#125;, current loop &#123;1&#125;'.format(counter, correct_iter))</span></span><br><span class="line">            best_omega = omega <span class="keyword">if</span>(correct_iter&gt;largest_iter) <span class="keyword">else</span> best_omega</span><br><span class="line">            best_b = b <span class="keyword">if</span>(correct_iter&gt;largest_iter) <span class="keyword">else</span> best_b</span><br><span class="line">            largest_iter = correct_iter <span class="keyword">if</span>(correct_iter&gt;largest_iter) <span class="keyword">else</span> largest_iter</span><br><span class="line">            counter += <span class="number">1</span></span><br><span class="line">            correct_iter = <span class="number">0</span></span><br><span class="line">        correct_iter += <span class="number">1</span></span><br><span class="line"></span><br><span class="line">        <span class="comment"># Conditions to exit the loop</span></span><br><span class="line">        <span class="keyword">if</span> correct_iter &gt; <span class="number">0.005</span> * size:</span><br><span class="line">            print(<span class="string">'iteration &#123;0&#125;, current loop &#123;1&#125;'</span>.format(counter, correct_iter))</span><br><span class="line">            print(<span class="string">'omega: &#123;0&#125;'</span>.format(best_omega))</span><br><span class="line">            print(<span class="string">'b: &#123;0&#125;'</span>.format(best_b))</span><br><span class="line">            <span class="keyword">break</span></span><br><span class="line">        <span class="keyword">if</span> counter &gt; max_iter:</span><br><span class="line">            print(<span class="string">'Reached maximum iteration &#123;0&#125; steps.'</span>.format(max_iter))</span><br><span class="line">            print(<span class="string">'omega: &#123;0&#125;'</span>.format(best_omega))</span><br><span class="line">            print(<span class="string">'b: &#123;0&#125;'</span>.format(best_b))</span><br><span class="line">            <span class="keyword">break</span></span><br><span class="line">    <span class="keyword">return</span> SGD(best_omega, best_b)</span><br></pre></td></tr></table></figure>
<p>Testing our model on the test set:</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">sgd = SGD_train(X_train, y_train_3, <span class="number">0.4</span>, <span class="number">50000</span>)</span><br><span class="line">y_testres = sgd.predict(X_test)</span><br><span class="line"></span><br><span class="line">success = <span class="number">0.0</span></span><br><span class="line">total = <span class="number">0.0</span></span><br><span class="line">rate = <span class="number">0.0</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">0</span>, <span class="number">10000</span>):</span><br><span class="line">    <span class="keyword">if</span> y_testres[i] == y_test_3[i]:</span><br><span class="line">        success += <span class="number">1</span></span><br><span class="line">    total += <span class="number">1</span></span><br><span class="line">rate = success / total</span><br><span class="line">print(<span class="string">"Success: &#123;0&#125;. Total: &#123;1&#125;. The accuracy on the test set is &#123;2&#125;"</span>.format(success, total, rate))</span><br></pre></td></tr></table></figure>
<pre><code>[-1 -1 -1 ... -1 -1 -1]
iteration 42632, current loop 301
omega: [ 0.0000e+00  0.0000e+00  0.0000e+00  0.0000e+00  0.0000e+00  0.0000e+00
  0.0000e+00  0.0000e+00  0.0000e+00  0.0000e+00  0.0000e+00  0.0000e+00
  0.0000e+00  0.0000e+00  0.0000e+00  ..........  0.0000e+00  0.0000e+00
  0.0000e+00  0.0000e+00  0.0000e+00  0.0000e+00]
b: -1123.0
Success: 8990.0. Total: 10000.0. The accuracy on the test set is 0.899</code></pre>
<p>By observing the results, the overall accuracy on the test set reached 89.9%, the same as the SGDClassifier in the Scikit-learn module.</p>
<p>We may think that 89.9% may not be a satisfactory result. That is because we used a linear model, but the dataset is not linear separable. In order to improve the result, try using the KNN algorithm, which will be covered in later posts.</p>

          
            <div class='article_footer'>
              
                
  
    
    



  

  
    
    



  

  
    
    

    <section class="widget copyright  desktop mobile">
        <div class='content'>
            
                <blockquote>
                    
                        
                                    <p>博客内容遵循 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 协议。转载请保留原文链接和作者。</p>

                                        
                                            
                </blockquote>
                
        </div>
    </section>
  

  


              
            </div>
          
        </div>
        
          


  <section class='meta' id="footer-meta">
    <div class='new-meta-box'>
      
        
          <div class="new-meta-item date" itemprop="dateUpdated" datetime="2021-02-15T10:25:24+08:00">
  <a class='notlink'>
    <i class="fas fa-edit fa-fw" aria-hidden="true"></i>
    <p>更新于：2021年2月15日 10:25</p>
  </a>
</div>

        
      
        
          
  
  <div class="new-meta-item meta-tags"><a class="tag" href="/junblog/tags/AI/" rel="nofollow"><i class="fas fa-hashtag fa-fw" aria-hidden="true"></i><p>AI</p></a></div> <div class="new-meta-item meta-tags"><a class="tag" href="/junblog/tags/Python/" rel="nofollow"><i class="fas fa-hashtag fa-fw" aria-hidden="true"></i><p>Python</p></a></div> <div class="new-meta-item meta-tags"><a class="tag" href="/junblog/tags/Machine-Learning/" rel="nofollow"><i class="fas fa-hashtag fa-fw" aria-hidden="true"></i><p>Machine Learning</p></a></div>


        
      
        
          
  <div class="new-meta-item share -mob-share-list">
  <div class="-mob-share-list share-body">
    
      
        <a class="-mob-share-qq" title="" rel="external nofollow noopener noreferrer"
          
          href="http://connect.qq.com/widget/shareqq/index.html?url=https://heliumhe.gitee.io/2021/02/11/B002%20Classification%20-%20SGD/&title=B002 Classification - SGD Method - Jun's Blog&summary=What is a classification problem?
Imagine an elementary school student is given a batch of learning materials: lots of pictures of handwitten digits. His parents is teaching him, "this is 1, o-n-e, one.""That is 5, f-i-v-e, five". And the student gradually learn to identify the digits 0~9 by their shapes. Now, whoever write a number, the little boy can name it correctly.
The above process is what classification problems look like:

First, given a dataset with labels, called training set, to the machine
Next, using some kind of algorithm, the machine learns to classify data of different labels based on the training set.
Then, we can use a test set to check the effectiveness of the learning process. If the machine is not satisfying, we can improve the algorithm or give better training sets to retrain the computer, until it is satisfying.
Finally, the machine can be put into practical use.
"
          
          >
          
            <img src="https://cdn.jsdelivr.net/gh/xaoxuu/cdn-assets/logo/128/qq.png">
          
        </a>
      
    
      
        <a class="-mob-share-qzone" title="" rel="external nofollow noopener noreferrer"
          
          href="https://sns.qzone.qq.com/cgi-bin/qzshare/cgi_qzshare_onekey?url=https://heliumhe.gitee.io/2021/02/11/B002%20Classification%20-%20SGD/&title=B002 Classification - SGD Method - Jun's Blog&summary=What is a classification problem?
Imagine an elementary school student is given a batch of learning materials: lots of pictures of handwitten digits. His parents is teaching him, "this is 1, o-n-e, one.""That is 5, f-i-v-e, five". And the student gradually learn to identify the digits 0~9 by their shapes. Now, whoever write a number, the little boy can name it correctly.
The above process is what classification problems look like:

First, given a dataset with labels, called training set, to the machine
Next, using some kind of algorithm, the machine learns to classify data of different labels based on the training set.
Then, we can use a test set to check the effectiveness of the learning process. If the machine is not satisfying, we can improve the algorithm or give better training sets to retrain the computer, until it is satisfying.
Finally, the machine can be put into practical use.
"
          
          >
          
            <img src="https://cdn.jsdelivr.net/gh/xaoxuu/cdn-assets/logo/128/qzone.png">
          
        </a>
      
    
      
        <a class="-mob-share-weibo" title="" rel="external nofollow noopener noreferrer"
          
          href="http://service.weibo.com/share/share.php?url=https://heliumhe.gitee.io/2021/02/11/B002%20Classification%20-%20SGD/&title=B002 Classification - SGD Method - Jun's Blog&summary=What is a classification problem?
Imagine an elementary school student is given a batch of learning materials: lots of pictures of handwitten digits. His parents is teaching him, "this is 1, o-n-e, one.""That is 5, f-i-v-e, five". And the student gradually learn to identify the digits 0~9 by their shapes. Now, whoever write a number, the little boy can name it correctly.
The above process is what classification problems look like:

First, given a dataset with labels, called training set, to the machine
Next, using some kind of algorithm, the machine learns to classify data of different labels based on the training set.
Then, we can use a test set to check the effectiveness of the learning process. If the machine is not satisfying, we can improve the algorithm or give better training sets to retrain the computer, until it is satisfying.
Finally, the machine can be put into practical use.
"
          
          >
          
            <img src="https://cdn.jsdelivr.net/gh/xaoxuu/cdn-assets/logo/128/weibo.png">
          
        </a>
      
    
      
        
        <div class='hoverbox'>
          <a><img src="https://cdn.jsdelivr.net/gh/xaoxuu/cdn-assets/logo/128/wechat.png"></a>
          <div class='target'>
            <img src="">
          </div>
        </div>
      
    
  </div>
</div>



        
      
    </div>
  </section>


        
        
          <div class="prev-next">
            
              <a class='prev' href='/junblog/2021/02/19/R%20Basics/'>
                <p class='title'><i class="fas fa-chevron-left" aria-hidden="true"></i>R Basics</p>
                <p class='content'>Vectors
To create a vector, use the c command, which stands for concatenate or combine.
1&gt; v...</p>
              </a>
            
            
              <a class='next' href='/junblog/2021/01/23/%E6%95%B0%E6%8D%AE%E5%BA%93%E6%A6%82%E8%AE%BA%E5%A4%8D%E4%B9%A0/'>
                <p class='title'>数据库概论知识点总结<i class="fas fa-chevron-right" aria-hidden="true"></i></p>
                <p class='content'>数据库系统的基本概念
从数据到数据库
数据
数据的概念
数据：数据的内容是信息；数据的表现形式是符号记录
数据的分类

按数据加工程度分：分为三次数据、二次数据、一次数据、零次数据...</p>
              </a>
            
          </div>
        
      </section>
    </article>
  

  
    <!-- 显示推荐文章和评论 -->



  <article class="post white-box reveal comments blur">
    <section class="article typo">
      <p ct><i class='fas fa-comments'></i> 评论</p>
      
        <p cst>读者们可以在此处进行交流</p>
      
      
      
      
      
      
        <section id="comments">
          <div id="valine_container" class="valine_thread">
            <i class="fas fa-cog fa-spin fa-fw fa-2x"></i>
          </div>
        </section>
      
      
    </section>
  </article>


  




<!-- 根据页面mathjax变量决定是否加载MathJax数学公式js -->



  <script>
    window.subData = {
      title: 'B002 Classification - SGD Method',
      tools: true
    }
  </script>


</div>
<aside class='l_side'>
  
  
    
    



  <section class="widget toc-wrapper blur desktop mobile" id="toc-div" >
    
  <header>
    
      <i class="fas fa-list fa-fw" aria-hidden="true"></i><span class='name'>本文目录</span>
    
  </header>


    <div class='content'>
        <ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#what-is-a-classification-problem"><span class="toc-number">1.</span> <span class="toc-text">What is a classification problem?</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#sgd-as-a-binary-classifier"><span class="toc-number">2.</span> <span class="toc-text">SGD as a binary classifier</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#mathematical-explanation-of-sgd-method"><span class="toc-number">3.</span> <span class="toc-text">Mathematical explanation of SGD method</span></a></li></ol>
    </div>
  </section>


  


</aside>


  
  <footer class="clearfix">
    <br><br>
    
      
        <div class="aplayer-container">
          


        </div>
      
    
      
        <br>
        <div class="social-wrapper">
          
            
              <a href="/junblog/atom.xml"
                class="social fas fa-rss flat-btn"
                target="_blank"
                rel="external nofollow noopener noreferrer">
              </a>
            
          
            
              <a href="mailto:hejunyuan02@126.com"
                class="social fas fa-envelope flat-btn"
                target="_blank"
                rel="external nofollow noopener noreferrer">
              </a>
            
          
            
              <a href="https://music.163.com/#/user/home?id=63035382"
                class="social fas fa-headphones-alt flat-btn"
                target="_blank"
                rel="external nofollow noopener noreferrer">
              </a>
            
          
        </div>
      
    
      
        本站使用
        <a href="https://volantis.js.org/" target="_blank" class="codename">Volantis</a>
        作为主题，总访问量为
          <span id="busuanzi_value_site_pv"><i class="fas fa-circle-notch fa-spin fa-fw" aria-hidden="true"></i></span>
          次
        
      
    
      
        <div class='copyright'>
        <p><a href="https://junyuanhe.github.io/" target="_blank" rel="noopener">Copyright © 2019-2020 Jun</a></p>

        </div>
      
    
  </footer>

<script>setLoadingBarProgress(80);</script>


      <script>setLoadingBarProgress(60);</script>
    </div>
    <a class="s-top fas fa-arrow-up fa-fw" href='javascript:void(0)'></a>
  </div>
  
<script src="https://cdn.jsdelivr.net/npm/jquery@3.4/dist/jquery.min.js"></script>


  <script>
    
    var SEARCH_SERVICE = "hexo" || "hexo";
    var ROOT = "/junblog/" || "/";
    if (!ROOT.endsWith('/')) ROOT += '/';
  </script>





  <script async src="https://cdn.jsdelivr.net/gh/xaoxuu/cdn-volantis@2/js/instant_page.js" type="module" defer integrity="sha384-OeDn4XE77tdHo8pGtE1apMPmAipjoxUQ++eeJa6EtJCfHlvijigWiJpD7VDPWXV1"></script>


  <script src="https://cdn.jsdelivr.net/npm/scrollreveal@4.0.6/dist/scrollreveal.min.js"></script>
  <script type="text/javascript">
    $(function() {
      ScrollReveal().reveal('.l_main .reveal', {
        distance: '8px',
        duration: '800',
        interval: '100',
        scale: '1'
      });
    });
  </script>


  
<script src="https://cdn.jsdelivr.net/npm/node-waves@0.7.6/dist/waves.min.js"></script>

  <script type="text/javascript">
    $(function() {
      Waves.attach('.flat-btn', ['waves-button']);
      Waves.attach('.float-btn', ['waves-button', 'waves-float']);
      Waves.attach('.float-btn-light', ['waves-button', 'waves-float', 'waves-light']);
      Waves.attach('.flat-box', ['waves-block']);
      Waves.attach('.float-box', ['waves-block', 'waves-float']);
      Waves.attach('.waves-image');
      Waves.init();
    });
  </script>


  <script defer src="https://cdn.jsdelivr.net/gh/xaoxuu/cdn-busuanzi@2.3/js/busuanzi.pure.mini.js"></script>



  
  
  
    
<script src="https://cdn.jsdelivr.net/npm/jquery-backstretch@2.1.18/jquery.backstretch.min.js"></script>

    <script type="text/javascript">
      $(function(){
        var imgs=["https://cdn.jsdelivr.net/gh/xaoxuu/cdn-wallpaper/abstract/41F215B9-261F-48B4-80B5-4E86E165259E.jpeg", "https://cdn.jsdelivr.net/gh/xaoxuu/cdn-wallpaper/abstract/BBC19066-E176-47C2-9D22-48C81EE5DF6B.jpeg", "https://cdn.jsdelivr.net/gh/xaoxuu/cdn-wallpaper/abstract/B18FCBB3-67FD-48CC-B4F3-457BA145F17A.jpeg", "https://cdn.jsdelivr.net/gh/xaoxuu/cdn-wallpaper/abstract/67239FBB-E15D-4F4F-8EE8-0F1C9F3C4E7C.jpeg"];
        if ('true' == 'true') {
          function shuffle(arr){
            /*From countercurrent-time*/
            var n = arr.length;
            while(n--) {
              var index = Math.floor(Math.random() * n);
              var temp = arr[index];
              arr[index] = arr[n];
              arr[n] = temp;
            }
          }
          shuffle(imgs);
        }
        if ('.cover') {
          $('.cover').backstretch(
            imgs,
          {
            duration: "20000",
            fade: "1500"
          });
        } else {
          $.backstretch(
            imgs,
          {
            duration: "20000",
            fade: "1500"
          });
        }
      });
    </script>
  











  
    
<script src="/junblog/js/valine.js"></script>

  
  <script>
  var GUEST_INFO = ['nick','mail','link'];
  var meta = 'nick,mail'.split(',').filter(function(item){
    return GUEST_INFO.indexOf(item) > -1
  });
  var REQUIRED_FIELDS = ['nick','mail','link'];
  var requiredFields = 'nick,mail'.split(',').filter(function(item){
    return REQUIRED_FIELDS.indexOf(item) > -1
  });
  var valine = new Valine();
  function emoji(path, idx, ext) {
      return path + "/" + path + "-" + idx + "." + ext;
  }
  var emojiMaps = {};
  for (var i = 1; i <= 54; i++) {
    emojiMaps['tieba-' + i] = emoji('tieba', i, 'png');
  }
  for (var i = 1; i <= 101; i++) {
    emojiMaps['qq-' + i] = emoji('qq', i, 'gif');
  }
  for (var i = 1; i <= 116; i++) {
    emojiMaps['aru-' + i] = emoji('aru', i, 'gif');
  }
  for (var i = 1; i <= 125; i++) {
    emojiMaps['twemoji-' + i] = emoji('twemoji', i, 'png');
  }
  for (var i = 1; i <= 4; i++) {
    emojiMaps['weibo-' + i] = emoji('weibo', i, 'png');
  }
  valine.init({
    el: '#valine_container',
    meta: meta,
    
    appId: "GbPm6UIzHrGduLaANgBIdhkf-gzGzoHsz",
    appKey: "SFuacIL4IJSnGk9TDX46eb0Y",
    placeholder: "快来评论吧~",
    pageSize:'10',
    avatar:'robohash',
    lang:'zh-cn',
    visitor: 'true',
    highlight: 'true',
    mathJax: 'true',
    enableQQ: 'true',
    requiredFields: requiredFields,
    emojiCDN: 'https://cdn.jsdelivr.net/gh/xaoxuu/cdn-assets/emoji/valine/',
    emojiMaps: emojiMaps
  })
  </script>





  
<script src="/junblog/js/app.js"></script>



  
<script src="https://cdn.jsdelivr.net/gh/xaoxuu/cdn-volantis@2.6.5/js/search.js"></script>







<!-- 复制 -->

  <script src="https://cdn.jsdelivr.net/npm/clipboard@2/dist/clipboard.min.js"></script>
<script>
  function wait(callback, seconds) {
    var timelag = null;
    timelag = window.setTimeout(callback, seconds);
  }
  !function (e, t, a) {
    var initCopyCode = function(){
      var copyHtml = '';
      copyHtml += '<button class="btn-copy" data-clipboard-snippet="">';
      copyHtml += '<i class="fas fa-copy"></i><span>COPY</span>';
      copyHtml += '</button>';
      $(".highlight .code pre").before(copyHtml);
      $(".article pre code").before(copyHtml);
      var clipboard = new ClipboardJS('.btn-copy', {
        target: function(trigger) {
          return trigger.nextElementSibling;
        }
      });
      clipboard.on('success', function(e) {
        let $btn = $(e.trigger);
        $btn.addClass('copied');
        let $icon = $($btn.find('i'));
        $icon.removeClass('fa-copy');
        $icon.addClass('fa-check-circle');
        let $span = $($btn.find('span'));
        $span[0].innerText = 'COPIED';
        
        wait(function () { // 等待两秒钟后恢复
          $icon.removeClass('fa-check-circle');
          $icon.addClass('fa-copy');
          $span[0].innerText = 'COPY';
        }, 2000);
      });
      clipboard.on('error', function(e) {
        e.clearSelection();
        let $btn = $(e.trigger);
        $btn.addClass('copy-failed');
        let $icon = $($btn.find('i'));
        $icon.removeClass('fa-copy');
        $icon.addClass('fa-times-circle');
        let $span = $($btn.find('span'));
        $span[0].innerText = 'COPY FAILED';
        
        wait(function () { // 等待两秒钟后恢复
          $icon.removeClass('fa-times-circle');
          $icon.addClass('fa-copy');
          $span[0].innerText = 'COPY';
        }, 2000);
      });
    }
    initCopyCode();
  }(window, document);
</script>




<!-- fancybox -->
<script src="https://cdn.jsdelivr.net/gh/fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.js"></script>
<script>
  function pjax_fancybox() {
    $(".article-entry").find("img").not('.inline').not('a img').each(function () { //渲染 fancybox
      var element = document.createElement("a"); // a 标签
      $(element).attr("pjax-fancybox", "");  // 过滤 pjax
      $(element).attr("href", $(this).attr("src"));
      if ($(this).attr("data-original")) {
        $(element).attr("href", $(this).attr("data-original"));
      }
      $(element).attr("data-fancybox", "images");
      var caption = "";   // 描述信息
      if ($(this).attr('alt')) {  // 标准 markdown 描述信息
        $(element).attr('data-caption', $(this).attr('alt'));
        caption = $(this).attr('alt');
      }
      var div = document.createElement("div");
      $(div).addClass("fancybox");
      $(this).wrap(div); // 最外层套 div ，其实主要作用还是 class 样式
      var span = document.createElement("span");
      $(span).addClass("image-caption");
      $(span).text(caption); // 加描述
      $(this).after(span);  // 再套一层描述
      $(this).wrap(element);  // 最后套 a 标签
    })
    $(".article-entry").find("img").fancybox({
      selector: '[data-fancybox="images"]',
      hash: false,
      loop: false,
      closeClick: true,
      helpers: {
        overlay: {closeClick: true}
      },
      buttons: [
        "zoom",
        "close"
      ]
    });
  };
  $(function () {
    pjax_fancybox();
  });
</script>





  <script>setLoadingBarProgress(100);</script>
</body>
</html>
